<template>
  <div class="editor">
    <!-- 左侧工具栏 -->
    <div class="editor__toolbar">
      <div class="editor__toolbar-group">
        <!-- 文件导入按钮 -->
        <el-tooltip content="文件导入" placement="right">
          <el-button class="editor__tool-btn" @click="handleImportFile">
            <el-icon><Files /></el-icon>
          </el-button>
        </el-tooltip>

        <!-- 保存草稿按钮 -->
        <el-tooltip content="保存草稿" placement="right">
          <el-button class="editor__tool-btn" :loading="isSaving" @click="handleSaveDraft">
            <el-icon><Document /></el-icon>
          </el-button>
        </el-tooltip>

        <!-- 发布文章按钮 -->
        <el-tooltip content="发布文章" placement="right">
          <el-button class="editor__tool-btn" type="primary" @click="handlePublish">
            <el-icon><Position /></el-icon>
          </el-button>
        </el-tooltip>

        <!-- 文章设置按钮 -->
        <el-tooltip content="文章设置" placement="right">
          <el-button
            class="editor__tool-btn"
            :class="{ 'is-active': showConfig }"
            @click="$emit('update:showConfig', !showConfig)"
          >
            <el-icon><Setting /></el-icon>
          </el-button>
        </el-tooltip>

        <!-- 显示目录按钮 -->
        <el-tooltip content="显示目录" placement="right">
          <el-button
            class="editor__tool-btn"
            :class="{ 'is-active': showCatalog }"
            @click="$emit('toggle-catalog')"
          >
            <el-icon><Menu /></el-icon>
          </el-button>
        </el-tooltip>

        <!-- 素材库按钮 -->
        <el-tooltip content="素材库" placement="right">
          <el-button class="editor__tool-btn" @click="$emit('open-media-library')">
            <el-icon><Picture /></el-icon>
          </el-button>
        </el-tooltip>
      </div>
    </div>

    <!-- 编辑器主体 -->
    <div class="editor__main" :class="{ 'is-collapsed': showConfig }">
      <!-- 文章标题输入 -->
      <div class="editor__title-wrapper">
        <input
          :value="title"
          @input="$emit('update:title', $event.target.value)"
          class="editor__title-input"
          placeholder="输入文章标题..."
        />
        <div class="editor__save-status">
          <span :class="['save-status-dot', props.saveStatusType]"></span>
          {{ saveStatusText }}
        </div>
      </div>

      <!-- Markdown编辑器 -->
      <div class="editor__md-wrapper">
        <md-editor
          ref="editorRef"
          v-model="editorContent"
          :theme="editorTheme"
          @onChange="handleEditorChange"
          @onSave="handleSaveContent"
          :toolbars="toolbars"
          :preview="editorConfig.preview"
          editor-id="publish-editor"
          :mode="editorConfig.mode"
          :default-mode="editorConfig.mode"
          :show-code-row-number="false"
          noUploadImg
          autoFocus
          :tab-width="2"
          :preview-theme="editorConfig.previewTheme"
          :scrollStyle="true"
          :previewOnly="false"
          :noKatex="true"
          @onHtmlChanged="handleHtmlChanged"
          @onGetCatalog="handleGetCatalog"
          :showCatalog="showCatalog"
        />
      </div>
    </div>
  </div>
</template>

<script setup>
/**
 * Markdown编辑器组件
 *
 * 功能：
 * 1. Markdown 文档编辑与预览
 * 2. 文章标题编辑
 * 3. 文章保存与发布
 * 4. 目录显示与导航
 * 5. 素材库集成
 */
import { ref, watch } from 'vue'
import { MdEditor } from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
import { Setting, Picture, Document, Position, Menu, Files } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

/**
 * Props 定义
 */
const props = defineProps({
  /** 文章标题 */
  title: String,

  /** 文章内容 - Markdown格式 */
  content: String,

  /** 控制配置面板是否显示 */
  showConfig: Boolean,

  /** 控制目录是否显示 */
  showCatalog: Boolean,

  /** 控制素材库是否显示 */
  showMediaLibrary: Boolean,

  /** 是否正在保存 */
  isSaving: Boolean,

  /** 保存状态文本 */
  saveStatusText: String,

  /** 保存状态类型 */
  saveStatusType: {
    type: String,
    default: 'success',
  },

  /**
   * 编辑器主题
   * 可选值: 'light', 'dark'
   */
  editorTheme: {
    type: String,
    default: 'light',
  },

  /**
   * 编辑器配置
   * 控制编辑器的行为和外观
   */
  editorConfig: {
    type: Object,
    default: () => ({
      mode: 'editable', // 编辑模式
      preview: true, // 开启预览
      previewTheme: 'default', // 预览主题
    }),
  },

  /** 文章表单数据 */
  articleForm: {
    type: Object,
    default: () => ({}),
  },
})

/**
 * 事件定义
 */
const emit = defineEmits([
  'update:title', // 更新标题
  'update:content', // 更新内容
  'update:showConfig', // 更新配置面板显示状态
  'update:showMediaLibrary', // 更新素材库显示状态
  'save-draft', // 保存草稿
  'publish', // 发布文章
  'toggle-catalog', // 切换目录显示
  'editor-change', // 编辑器内容变化
  'html-changed', // HTML内容变化
  'get-catalog', // 获取目录
  'open-media-library', // 打开素材库
])

/**
 * 编辑器引用，用于获取编辑器实例和方法
 */
const editorRef = ref(null)

/**
 * 编辑器内容，用于双向绑定
 */
const editorContent = ref(props.content || '')

/**
 * 监听标题变化，确保与父组件同步
 */
watch(
  () => props.title,
  (newTitle) => {
    if (newTitle !== undefined) {
      emit('update:title', newTitle)
    }
  },
  { immediate: true },
)

/**
 * 工具栏配置
 * 定义编辑器顶部工具栏显示的功能按钮
 */
const toolbars = [
  'bold', // 粗体
  'italic', // 斜体
  'strikethrough', // 删除线
  'heading', // 标题
  'line', // 分割线
  'quote', // 引用
  'code', // 代码块
  'link', // 链接
  'image', // 图片
  'table', // 表格
  'list', // 无序列表
  'ordered-list', // 有序列表
  'hr', // 水平线
  'undo', // 撤销
  'redo', // 重做
  'save', // 保存
]

/**
 * 处理事件与方法
 */

/**
 * 保存内容（编辑器 onSave 事件，仅保存，不跳转）
 */
const handleSaveContent = () => {
  emit('save-content')
}

/**
 * 保存草稿（侧边栏按钮，保存并跳转）
 */
const handleSaveDraft = () => {
  emit('save-draft')
}

/**
 * 发布文章
 */
const handlePublish = () => {
  emit('publish')
}

/**
 * 导入文件
 */
const handleImportFile = () => {
  // 创建文件输入元素
  const fileInput = document.createElement('input')
  fileInput.type = 'file'
  fileInput.accept = '.md,.txt'

  // 处理文件选择
  fileInput.onchange = (e) => {
    const file = e.target.files[0]
    if (!file) return

    // 读取文件内容
    const reader = new FileReader()
    reader.onload = (event) => {
      editorContent.value = event.target.result
      emit('update:content', editorContent.value)
    }
    reader.readAsText(file)
  }

  // 触发文件选择
  fileInput.click()
}

/**
 * 处理编辑器内容变化
 * @param {string} content - 新的编辑器内容
 */
const handleEditorChange = (content) => {
  editorContent.value = content
  emit('editor-change', content)
}

/**
 * 处理HTML内容变化
 * @param {string} html - 新的HTML内容
 */
const handleHtmlChanged = (html) => {
  emit('html-changed', html)
}

/**
 * 处理目录数据变化
 * @param {Array} catalog - 目录数据
 */
const handleGetCatalog = (catalog) => {
  emit('get-catalog', catalog)
}

/**
 * 监听器
 */

/**
 * 监听 props.content 的变化，同步到编辑器内容
 */
watch(
  () => props.content,
  (newVal) => {
    if (newVal !== editorContent.value) {
      editorContent.value = newVal
    }
  },
  { immediate: true },
)

/**
 * 监听编辑器内容变化，同步到父组件
 */
watch(
  editorContent,
  (newVal) => {
    emit('update:content', newVal)
  },
  { immediate: true },
)

/**
 * 暴露组件方法和属性给父组件
 */
defineExpose({
  editorRef,
  toggleCatalog: (show) => {
    editorRef.value?.toggleCatalog?.(show)
  },
  // 直接暴露获取编辑器实例的方法，方便父组件使用
  getEditorInstance: () => {
    return editorRef.value?.getEditorInstance?.()
  },
})
</script>

<style lang="scss" scoped>
// 导入主题变量和混合器
@use '@/assets/styles/theme/base.scss' as *;
@use '@/assets/styles/mixins.scss' as *;
@use 'sass:color';

/**
 * 编辑器组件样式
 * 使用BEM命名规范
 */
.editor {
  height: 100%;
  display: flex;
  position: relative;
  overflow: hidden;

  /**
   * 左侧工具栏
   * 包含各种功能按钮
   */
  &__toolbar {
    width: 64px;
    height: 100%;
    background-color: $bg-light;
    border-right: 1px solid $border-base;
    padding: 20px 0;
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  /**
   * 工具栏按钮组
   */
  &__toolbar-group {
    display: flex;
    flex-direction: column;
    gap: 16px;
    align-items: center;
    width: 100%;

    :deep(.el-button + .el-button) {
      margin-left: 0;
    }
  }

  /**
   * 工具按钮
   */
  &__tool-btn {
    width: 48px;
    height: 48px;
    padding: 0;
    border-radius: $radius-base;
    @include flex-center;
    @include transition(all);

    &.is-active {
      color: $color-primary;
      background-color: color.mix($color-primary, $bg-base, $weight: 10%);
    }

    .el-icon {
      font-size: 20px;
    }

    &.el-button--primary {
      .el-icon {
        color: #fff;
      }
    }

    // 增加一些过渡效果
    &:hover {
      transform: translateX(2px);
    }

    &:active {
      transform: translateX(0);
    }
  }

  /**
   * 编辑器主体
   * 包含标题输入和Markdown编辑器
   */
  &__main {
    flex: 1;
    height: 100%;
    @include transition(all);
    display: flex;
    flex-direction: column;
    position: relative;

    &.is-collapsed {
      margin-right: 380px;
    }
  }

  /**
   * 标题输入区
   */
  &__title-wrapper {
    padding: 16px 24px;
    border-bottom: 1px solid $border-light;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }

  /**
   * 标题输入框
   */
  &__title-input {
    flex: 1;
    width: 100%;
    font-size: $font-size-h3;
    font-weight: 500;
    color: $text-primary;
    border: none;
    outline: none;
    background: none;
    height: 32px;
    line-height: 32px;

    &::placeholder {
      color: $text-placeholder;
    }
  }

  /**
   * 保存状态显示
   */
  &__save-status {
    font-size: $font-size-small;
    color: $text-secondary;
    white-space: nowrap;
    display: flex;
    align-items: center;
    .save-status-dot {
      display: inline-block;
      width: 8px;
      height: 8px;
      border-radius: 50%;
      margin-right: 6px;
      &.success {
        background: #52c41a;
      }
      &.danger {
        background: #ff4d4f;
      }
    }
  }

  /**
   * Markdown编辑器容器
   */
  &__md-wrapper {
    flex: 1;
    min-height: 0;

    :deep(.md-editor) {
      height: 100%;
      border: none;
      background: none;

      // 工具栏样式
      .md-editor-toolbar {
        background-color: $bg-base;
        padding: 8px 16px;

        svg {
          width: 28px;
          height: 28px;
        }

        button {
          padding: 10px 12px;
          margin: 0 3px;
          border-radius: $radius-base;
          @include transition(background-color);

          &:hover {
            background-color: $bg-hover;
          }
        }
      }

      // 移除所有可能影响滚动的样式，让编辑器使用默认行为
      .md-editor-content {
        flex: 1;
        min-height: 0;
      }

      // 添加目录相关样式
      .md-editor-catalog {
        background-color: $bg-base;
        border-left: 1px solid $border-base;

        .catalog-title {
          padding: 12px 16px;
          font-size: $font-size-body;
          font-weight: 500;
          color: $text-primary;
          border-bottom: 1px solid $border-light;
        }

        .catalog-list {
          padding: 12px 0;

          .catalog-item {
            padding: 6px 16px;
            cursor: pointer;
            color: $text-regular;
            @include transition(all);

            &:hover {
              color: $color-primary;
              background-color: color.mix($color-primary, $bg-base, $weight: 4%);
            }

            &.active {
              color: $color-primary;
              background-color: color.mix($color-primary, $bg-base, $weight: 8%);
            }
          }
        }
      }
    }
  }
}

/**
 * 动画效果
 */
@keyframes pulse {
  0% {
    transform: translateY(-50%) scale(0.8);
    opacity: 0.5;
  }
  50% {
    transform: translateY(-50%) scale(1.2);
    opacity: 1;
  }
  100% {
    transform: translateY(-50%) scale(0.8);
    opacity: 0.5;
  }
}
</style>
